var data = require('./data');

var count = 100000;
var factory = require('./exec');

var test = function(name, sample, cb) {
	var i = 0;
	var start, compileTime;
	var done = function(error, html) {
		i++;
    if (i === count) {
			var now = Date.now();
			compileTime = now - start;
		} else if (i === count*2) {
			var now = Date.now();
			cb(null, name, now - start, compileTime);
		}
	}
	start = Date.now();
	for (var j = 0; j < count; j++) {
		sample.prepare(data, done);
	}
	sample.prepare(data, function() {
		start = Date.now();
		for (var j = 0; j < count; j++) {
			sample.step(done);
		}
	});
};

var testUnescaped = function(name, sample, cb) {
	var i = 0;
	var start, compileTime;
	var done = function(error, html) {
		i++;
		if (i === count) {
			var now = Date.now();
			compileTime = now - start;
		} else if (i === count*2) {
			var now = Date.now();
			cb(null, name, now - start, compileTime);
		}
	}
	start = Date.now();
	for (var j = 0; j < count; j++) {
		sample.prepareUnescaped(data, done);
	}
	sample.prepareUnescaped(data, function() {
		start = Date.now();
		for (var j = 0; j < count; j++) {
			sample.step(done);
		}
	});
};

var samples = [
	{ name : 'EJS', sample : factory('../ejs.js') },
	{ name : 'old EJS', sample : factory('../ejs.old') },
	{ name : 'EJS without `with`', sample : factory('../ejs', {_with: false}) },
	{ name : 'old EJS without `with`', sample : factory('../ejs.old', {_with: false}) },
];

var runTests = function () {
	if (samples.length) {
		var sample = samples.pop();
		test(sample.name, sample.sample, function (err, name, escapedRunTime, escapedCompileTime) {
			testUnescaped(sample.name, sample.sample, function (err, name, unescapedRunTime, unescapedCompileTime) {
				console.log(name);
				console.log('  Escaped render time     : ' + escapedRunTime + 'ms');
        console.log('  Escaped compile time    : ' + escapedCompileTime + 'ms');
        console.log('  Unescaped render time   : ' + unescapedRunTime + 'ms');
        console.log('  Unescaped compile time  : ' + unescapedCompileTime + 'ms');
				console.log('  Total                   : ' + (escapedRunTime + escapedCompileTime + unescapedRunTime + unescapedCompileTime) + 'ms');
				console.log('');
				runTests();
			});
		});
	}
};

console.log('Rendering ' + count + ' templates:\n');
runTests();
